home *** CD-ROM | disk | FTP | other *** search
- *
- * ZKick V3.01 -- Copyright (C) 1991 by Daniel Zenchelsky
- *
- * This program may be freely copied, as long as all copyright
- * notices are left intact and unchanged.
- *
-
-
- SECTION code
-
- NOLIST
- INCLUDE "exec/types.i"
- INCLUDE "exec/initializers.i"
- INCLUDE "exec/libraries.i"
- INCLUDE "exec/lists.i"
- INCLUDE "exec/alerts.i"
- INCLUDE "exec/resident.i"
- INCLUDE "exec/memory.i"
- INCLUDE "exec/tasks.i"
- INCLUDE "exec/execbase.i"
- INCLUDE "libraries/expansion.i"
-
- INCLUDE "zkick.i"
- INCLUDE "mmu.i"
-
- LIST
-
- XDEF Reboot
- XDEF _MakeRomTag
- XDEF _config
- XDEF _connum
- XDEF _memory
- XDEF _memnum
- XDEF _Survive
- XDEF _MMU
-
- XDEF _NOMMU
- XDEF _NOCHECKSUM
- XDEF _NORESET
- XDEF _DEBUG
- XDEF _PRINT
- XDEF _LOADC0
- XDEF _V175
-
- XDEF _StartKick
-
- ;------ These don't have to be external, but it helps some
- ;------ debuggers to have them globally visible
- XDEF modName
- XDEF MemName
- XDEF _InitRoutine
- XDEF initDDescrip
- XDEF ABSEXECBASE
- XDEF SaveMem
- XDEF KickMem
- XDEF KickTag
- XDEF expansionname
- XDEF ExpansionBase
- XDEF ConfigCopy
- XDEF AddMem
- XDEF EndTag
- XDEF CheckSum
-
- XREF _LVOSumKickData
-
- XREF _LVOOpenLibrary
- XREF _LVOCloseLibrary
- XREF _LVOAddConfigDev
- XREF _LVOAllocConfigDev
- XREF _LVOCopyMem
- XREF _LVOAddMemList
- XREF _LVOSetFunction
- XREF _LVOSuperState
- XREF _LVOSupervisor
- XREF _LVODisable
-
- ;
- ; Offsets from ExecBase
- ;
-
- *KickMemPtr EQU $222
- *KickTagPtr EQU $226
- *KickCheckSum EQU $22a
- *WarmCapture EQU 50
- *CoolCapture EQU 46
- *ColdCapture EQU 42
- ExecVersion EQU $14
-
- ROMVersion EQU $FC0010
-
- VERSION: EQU 3
- REVISION: EQU 01
-
-
- _MakeRomTag:
- move.l ABSEXECBASE,a6
- ;
- ; Set up KickMemPtr
- ;
- lea.l KickMem+14,a0
- move.w #1,(a0)+ ; Number of Entries = 1
- lea.l SaveMem,a1
- move.l a1,(a0)+ ; Allocation Start
- lea.l EndTag-SaveMem,a1 ; Allocation Length
- move.l a1,(a0)+
- lea.l KickMem,a0
-
- move.l KickMemPtr(a6),(a0) ; old pointer in ln_Succ
-
- move.l a0,KickMemPtr(a6)
-
- ;
- ; Set up KickTagPtr
- ;
- lea KickTag,a0
-
- move.l KickTagPtr(a6),4(a0) ; Old pointer at the end of the table
- beq.s .nomore
-
- bset.b #7,4(a0) ; Bit 31 = Extend table
-
- .nomore:
- move.l a0,KickTagPtr(a6)
-
- ;
- ; Calculate checksum
- ;
-
- jsr _LVOSumKickData(a6)
- move.l d0,KickCheckSum(a6)
- ;
- ; Setup reboot code
- ;
- jsr SetVectors
- rts
-
- ;-----------------------------------------------------------------------
- ; From here on is protected from erasure during reboot
- ;-----------------------------------------------------------------------
-
- SaveMem:
-
- KickMem:
- DC.L 0,0,0,0,0,0
-
- KickTag:
- DC.L initDDescrip
- DC.L $0
-
- _StartKick: DC.L $00000000
- OldAddMemList: DC.L $00000000
- _Survive: DC.L $00000000
- _MMU: DC.L $00000000
- _NOMMU: DC.L $00000000
- _NOCHECKSUM: DC.L $00000000
- _NORESET: DC.L $00000000
- _DEBUG: DC.L $00000000
- _PRINT: DC.L $00000000
- _LOADC0: DC.L $00000000
- _V175: DC.L $00000000
-
- ;
- ; --- ColdReboot()
- ;
-
- XREF _LVOSupervisor
-
- MAGIC_ROMEND EQU $01000000 ;End of Kickstart ROM
- MAGIC_SIZEOFFSET EQU -$14 ;Offset from end of ROM to Kickstart size
- V36_EXEC EQU 36 ;Exec with the ColdReboot() function
- TEMP_ColdReboot EQU -726 ;Offset of the V36 ColdReboot function
-
-
- _ColdReboot: move.l ABSEXECBASE,a6
- cmp.w #V36_EXEC,LIB_VERSION(a6)
- blt.s old_exec
- jmp TEMP_ColdReboot(a6) ;Let Exec do it...
- ;NOTE: Control flow never returns to here
-
-
- ;---- manually reset the Amiga ---------------------------------------------
- old_exec: lea.l GoAway(pc),a5 ;address of code to execute
- jsr _LVOSupervisor(a6) ;trap to code at (a5)...
- ;NOTE: Control flow never returns to here
-
-
- ;-------------- MagicResetCode ---------DO NOT CHANGE-----------------------
- CNOP 0,4 ;IMPORTANT! Longword align!
- GoAway: lea.l MAGIC_ROMEND,a0 ;(end of ROM)
- sub.l MAGIC_SIZEOFFSET(a0),a0 ;(end of ROM)-(ROM size)=PC
- move.l 4(a0),a0 ;Get Initial Program Counter
- subq.l #2,a0 ;now points to second RESET
- reset ;first RESET instruction
- jmp (a0) ;CPU Prefetch executes this
- ;NOTE: the RESET and JMP instructions must share a longword!
- ;---------------------------------------DO NOT CHANGE-----------------------
-
- ;
- ; Set up the reboot routines
- ;
-
- SetVectors:
-
-
- PUTMSG <'SetVectors'>
-
- tst.l _LOADC0
- beq.s 1$
- move.l #0,MaxExtMem(a6)
-
- 1$: lea.l ColdRoutine,a0
- move.l a0,ColdCapture(a6)
-
- lea.l CoolRoutine,a0
- move.l a0,CoolCapture(a6)
-
- ; Recalculate checksum
-
- lea $22(a6),a0
- moveq #$16,d0
- moveq #0,d1
- sumloop:
- add.w (a0)+,d1
- dbra d0,sumloop
- not.w d1
- move.w d1,$52(a6)
-
- rts
-
- tmp: dc.l 0
-
- ColdRoutine:
-
- NS_PUTMSG <'ColdRoutine'>
-
- move.l a5,tmp ; We can't test ExecBase because 1.3
- ; will use the 2.0 ExecBase.
- and.w #$FFF0,tmp ; So we look at the return address
- cmp.w #$00F0,tmp ; to see if we are running from ROM.
- ; <-- Should check for $F80000-$FFFFFF
- bne DoneCold
-
- NS_PUTMSG <'Version 1.2/1.3 ColdCapture'>
-
- cmp.l #-$1,d6 ; Test to see if there is a delayed GURU
- beq NoGuru ; If not, skip this.
- move.l #$48454C50,0 ; move "HELP" to location 0
- ; KickStart 2.0 will take care of the rest
-
- NoGuru:
-
- cmp.l #$B7FC0004,$1e(a5) ; Verify that this is really 1.2/1.3
- bne.s skipfix
- move.l $3E(A6),A3 ; Skip version and >512k chip mem
- jmp $1e(a5) ; checks
-
- skipfix:
-
- NS_PUTMSG <'skipfix'>
-
- DoneCold:
- jmp (a5)
-
- CoolRoutine:
-
- PUTMSG <'CoolRoutine'>
-
- movem.l a0-a6/d0-d7,-(SP)
-
- move.l ABSEXECBASE,a6
-
- move.w ROMVersion,a0 ; If we're running under 2.0
- cmp.w ExecVersion(a6),a0 ; skip this.
- bne.s DoneCool
-
- PUTMSG <'Version 1.2/1.3 CoolCapture'>
-
- movea.l a6,a1 ; Keep exec 1.2/1.3 from stomping
- lea.l NewAddMemList,a0 ; on the first few bytes
- move.l a0,d0 ; of kickstart memory.
- lea.l _LVOAddMemList,a0
- jsr _LVOSetFunction(a6)
- move.l d0,OldAddMemList
-
- DoneCool:
- movem.l (SP)+,a0-a6/d0-d7
- rts
-
- NewAddMemList:
-
- PUTMSG <'NewAddMemList'>
-
- rts
-
- ;-----------------------------------------------------------------------
- ; A romtag structure. Both "exec" and "ramlib" look for
- ; this structure to discover magic constants about you
- ; (such as where to start running you from...).
- ;-----------------------------------------------------------------------
-
- ; Most people will not need a priority and should leave it at zero.
- ; the RT_PRI field is used for _configuring the roms. Use "mods" from
- ; wack to look at the other romtags in the system
-
- MYPRI EQU 107
-
- initDDescrip:
- ;STRUCTURE RT,0
- DC.W RTC_MATCHWORD ; UWORD RT_MATCHWORD
- DC.L initDDescrip ; APTR RT_MATCHTAG
- DC.L EndTag ; APTR RT_ENDSKIP
- DC.B RTF_COLDSTART ; UBYTE RT_FLAGS
- DC.B VERSION ; UBYTE RT_VERSION
- DC.B NT_UNKNOWN ; UBYTE RT_TYPE
- DC.B MYPRI ; BYTE RT_PRI
- DC.L modName ; APTR RT_NAME
- DC.L idString ; APTR RT_IDSTRING
- DC.L _InitRoutine ; APTR RT_INIT
-
-
- ; this is the name that the module will have
- modName: DC.B 'zkick.romtag',0
-
- idString: dc.b 'zkick.romtag 3.01 (7/10/91)',13,10,0
-
- MemName: dc.b 'zkick memory',0
-
- expansionname: dc.b 'expansion.library',0
-
- CNOP 0,4
-
- ABSEXECBASE EQU $00000004
- ExpansionBase: DC.L $00000000
- ConfigCopy: DC.L $00000000
-
-
- _InitRoutine:
-
- movem.l d0-d7/a0-a6,-(a7)
-
- PUTMSG <'InitRoutine'>
-
- move.l ABSEXECBASE,a6 ; If we're running under 1.2/1.3
- move.l ROMVersion,a0 ; we wan't to start KickStart
- cmp.l ExecVersion(a6),a0 ; from _StartKick
- bne okversion
-
- tst.l _NOCHECKSUM
- bne.s skipsum
-
- move.l _StartKick,a0 ; Checksum KickStart image
- move.l #$80000,d1 ; at _StartKick
- jsr CheckSum
- tst.l d0
- bne panic
-
- PUTMSG <'KickStart Checksum valid'>
-
- skipsum:
- ; Let's be doubly cautious:
- jsr _LVOSuperState(a6)
- move.l _StartKick,a0 ; Verify that there's a
- ; KickStart image at
- cmp.w #$4ef9,2(a0) ; _StartKick
- bne panic
-
- PUTMSG <'KickStart checks out OK'>
-
- tst.l _NOMMU
- bne.s 1$
-
- move.l ABSEXECBASE,a6 ; If there is an MMU
- jsr _LVODisable(a6) ; disable it before
- tst.l _MMU ; starting KickStart
- beq 1$
- move.l #0,a0
- jsr SetTC
-
- 1$:
- PUTMSG <'Jumping to KickStart'>
-
- move.l _StartKick,A0
- move.l 4(A0),A0
- jmp (A0) ; Start KickStart
-
- panic: ; Uh oh, doesn't look like
- ; KickStart at _StartKick
- PUTMSG <'panic!'>
-
- clr.l ColdCapture(a6)
- clr.l CoolCapture(a6)
- clr.l WarmCapture(a6) ; Clear vectors and reboot
- clr.l KickTagPtr(a6)
- clr.l KickMemPtr(a6)
-
- jmp Reboot
-
- okversion:
-
- PUTMSG <'okversion'>
-
- tst.l _Survive ; Do we want to survive?
- beq.s 2$
- jsr SetVectors ; Set up Capture vectors
- ; for reboot survival
-
- 2$: lea.l expansionname,A1
- clr.l D0
- jsr _LVOOpenLibrary(a6) ; Open expansion.library
- move.l D0,ExpansionBase
- tst.l D0
- bne.s 1$
- jmp exit
-
- 1$:
- lea.l _config,a2
- move.l _connum,a3
-
- PUTMSG <'Adding expansion devices'>
-
- loop:
- cmp.l #0,a3
- beq close
-
- move.l ExpansionBase,a6 ; For each configdev structure we
- jsr _LVOAllocConfigDev(a6) ; saved, allocate a fresh configdev
- move.l D0,ConfigCopy ; structure.
- tst.l D0
- bne.s 2$
- jmp close
-
- 2$:
- move.l a2,A0
- move.l ConfigCopy,A1 ; Copy the old configdev onto
- move.l #end_config-_config,D0 ; the new one
- move.l ABSEXECBASE,a6
- jsr _LVOCopyMem(a6)
-
- move.l ConfigCopy,A0
- move.l ExpansionBase,a6
- jsr _LVOAddConfigDev(a6) ; Add it to the configdev list
-
- PUTMSG <'Linked 1 ConfigDev'>
-
- subq.l #1,a3
- add.l #end_config-_config,a2 ; Go get another configdev structure
- jmp loop
-
- close:
- move.l ExpansionBase,A1
- move.l ABSEXECBASE,a6 ; Close expansion.library
- jsr _LVOCloseLibrary(a6)
-
- AddMem:
-
-
- PUTMSG <'Adding Memory'>
-
- lea _memory,a2 ; Do the same thing
- move.l _memnum,a3 ; for the memory lists
-
- AddMemLoop:
- cmp.l #0,a3
- beq.s exit
-
- move.l (a2),a0
- addq.l #4,a2
- move.l (a2),d0
- addq.l #4,a2
- move.l #MEMF_FAST+MEMF_PUBLIC,d1
- clr.l d2
- lea.l MemName,a1
- move.l ABSEXECBASE,a6
- jsr _LVOAddMemList(a6)
-
- PUTMSG <'Linked 1 mem board'>
-
- subq.l #1,a3
- jmp AddMemLoop
-
- exit:
- movem.l (a7)+,d0-d7/a0-a6
- rts
-
- CheckSum:
-
- PUTMSG <'CheckSum'>
-
- lsr.l #2,d1
- subq.l #1,d1
- moveq #0,d0
-
- 1$: add.l (a0)+,d0
- bcc.s 2$
- addq.l #1,d0
-
- 2$: dbra d1,1$
- sub.l #$10000,d1
- bpl.s 1$
- addq.l #1,d0
- rts
-
- ;======================================================================
- ;
- ; This function sets the MMU TC register. It assumes a 68020
- ; system with MMU, or a 68030 based system (eg, test for MMU before
- ; you call this, or you wind up in The Guru Zone).
- ;
- ; SetTC(ULONG)
- ; a0
- ;======================================================================
-
- SetTC:
-
- PUTMSG <'SetTC'>
-
- move.l 4,a6 ; Get ExecBase
- move.l a5,-(sp)
- lea.l 1$,a5 ; Get the start of the supervisor code
- CALLSYS Supervisor
- move.l (sp)+,a5
- rts
- 1$
- _PMOVE a0,tc ; Just set the TC register
-
- ; Was _PMOVE (a0),tc <-- Looked wrong!
- rte
-
- Reboot:
-
- PUTMSG <'Reboot'>
-
- tst.l _NOMMU
- bne.s nommu
-
- PUTMSG <'Disabling MMU'>
-
- move.l ABSEXECBASE,a6 ; If there is an MMU,
- jsr _LVODisable(a6) ; disable it before
- tst.l _MMU ; rebooting.
- beq nommu
- move.l #0,a0
- jsr SetTC
- nommu:
- jmp _ColdReboot
-
- EndCode:
-
- *********
-
- CNOP 0,4 ; LongWord Align (For CopyMem)
-
- _connum:
- DS.L 1
-
- _config:
- DS.L 17
- end_config:
- DS.L 17*7
-
- _memnum:
- DS.L 1
-
- _memory:
- DS.L 2
- end_memory:
- DS.L 2*7
-
- EndTag:
-
- END
-